// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 定义波段区间（可调整）
const lowZone = allNumbers.slice(0, 16);    // 01~16
const midZone = allNumbers.slice(16, 33);   // 17~33
const highZone = allNumbers.slice(33, 49);  // 34~49

/**
 * ✨ 波段策略
 * - 将号码划分为低/中/高三段
 * - 各选出频率最高的若干号码
 */
function select32ByBandBalance(temp) {
  const lowFreq = {}, midFreq = {}, highFreq = {};

  temp.forEach(({ number }) => {
    if (lowZone.includes(number)) {
      lowFreq[number] = (lowFreq[number] || 0) + 1;
    } else if (midZone.includes(number)) {
      midFreq[number] = (midFreq[number] || 0) + 1;
    } else if (highZone.includes(number)) {
      highFreq[number] = (highFreq[number] || 0) + 1;
    }
  });

  const top = (freqMap, count) =>
    _(freqMap)
      .toPairs()
      .orderBy(([num, cnt]) => cnt, "desc")  // 按频率降序排列
      .map(([num]) => num)
      .take(count)  // 取前 count 个
      .value();

  // 每段取一定数量（可调整比例）
  const selected = [
    ...top(lowFreq, 11),
    ...top(midFreq, 11),
    ...top(highFreq, 10),
  ];

  // 如果选出的号码不足 32 个，直接从未选中的号码中按顺序补充
  if (selected.length < 32) {
    const remain = allNumbers.filter((n) => !selected.includes(n));
    const needed = 32 - selected.length;
    selected.push(...remain.slice(0, needed));  // 直接从未选中号码中补充
  }

  return selected;
}

// ✅ 多窗口循环测试结果
const testResults = [];

for (let windowSize = 2; windowSize <= 200; windowSize++) {
  let correct = 0;
  let maxWrongStreak = 0;
  let currentWrongStreak = 0;
  const predictResults = [];

  allValues.forEach((item, index) => {
    const temp = allValues.slice(Math.max(0, index - windowSize), index);

    if (temp.length === 0) return;

    const selectedNumbers = select32ByBandBalance(temp);

    if (selectedNumbers.length !== 32) {
      throw new Error("选出的32个号码数量不正确");
    }

    try {
      const isHit = checkAccuracy(selectedNumbers, item.number);
      if (isHit) {
        correct += 1;
        currentWrongStreak = 0;
      } else {
        currentWrongStreak += 1;
        maxWrongStreak = Math.max(maxWrongStreak, currentWrongStreak);
      }
      predictResults.push(selectedNumbers);
    } catch (err) {
      console.error(`❌ checkAccuracy error at index ${index}: ${err.message}`);
    }
  });

  const total = predictResults.length;
  const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : 0;

  testResults.push({
    windowSize,
    total,
    correct,
    accuracy: Number(accuracy),
    maxWrongStreak,
  });
}

// ✅ 输出所有窗口测试结果
testResults.forEach((res) => {
  console.log(
    `windowSize = ${res.windowSize}, 准确率 = ${res.accuracy}%, 最大连续错误次数 = ${res.maxWrongStreak}`
  );
});

// ✅ 输出最佳结果
const bestAcc = _.maxBy(testResults, "accuracy");
const bestStable = _.minBy(testResults, "maxWrongStreak");

console.log("\n🎯 最佳准确率窗口:");
console.log(bestAcc);
console.log("\n🧱 最小连续错误窗口:");
console.log(bestStable);
